package core.util;

import cn.hutool.core.util.StrUtil;
import lombok.Cleanup;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * row 开始行 从1开始
 * column 处理列 从1开始
 */
@Slf4j
public class TransformCsvData {
    /**
     * 数据输出频率   默认10条输出一条
     */
    public static int frequency = 10;

    /**
     * 该方法默认不去头
     * @param readFile 读取文件路径
     * @param outputFile 输出文件路径 文件不存在自动创建
     * @param row       从第几行开始需要使用transfer进行处理
     * @param column    处理第几列
     * @param transfer  自定义数据处理方式
     */
    public static void transferData(String readFile, String outputFile, int row, int column, Transfer transfer) {
        transferData(readFile, outputFile, row, column, transfer, false);
    }

    /**
     * @param readFile 读取文件路径
     * @param outputFile 输出文件路径 文件不存在自动创建
     * @param row       从第几行开始需要使用transfer进行处理
     * @param column    处理第几列
     * @param transfer  自定义数据处理方式
     * @param decapitating 是否去头
     */
    @SneakyThrows
    public static void transferData(String readFile, String outputFile, int row, int column, Transfer transfer, boolean decapitating) {
        log.info("【数据转义】开始 readFile ->{},outputFile->{},row->{},column ->{},是否去头->{}", readFile, outputFile, row, column, decapitating);
        validateCsvPath(readFile);
        File file = new File(readFile);
        if (!file.exists()) {
            log.info("【获取读取文件】 读取文件不存在 readFile->{}", readFile);
            throw new RuntimeException("读取文件不存在");
        }
        @Cleanup FileInputStream in = new FileInputStream(file);
        @Cleanup InputStreamReader inReader = new InputStreamReader(in, "UTF-8");
        @Cleanup BufferedReader bufReader = new BufferedReader(inReader);


        validateCsvPath(outputFile);
        File exportFile = new File(outputFile);
        @Cleanup FileOutputStream out = new FileOutputStream(exportFile);

        String line = null;
        int i = 1;
        while ((line = bufReader.readLine()) != null) {
            if (i < row) {
                if (decapitating) {
                    log.info("【去除{}行】 line->{}", i, line);
                } else {
                    out.write(line.concat("\n").getBytes(StandardCharsets.UTF_8));
                    log.info("【保留{}行】 line->{}", i, line);
                }
                i++;
                continue;
            }

            String[] split = line.split(",");
            //获取等待处理的数据
            String target = split[column - 1];
            //处理数据
            split[column - 1] = transfer.transfer(target);

            String res = StrUtil.join(",", split).concat("\n");
            if (i % frequency == 0) {
                log.info("【写入{}行】 line->{} , 日志频率->{}", i, res.trim(), frequency);
            }
            out.write(res.getBytes(StandardCharsets.UTF_8));
//            System.out.print(res);
            i++;
        }
        log.info("本次共导出数据集{}条", i);
    }


    static void validateCsvPath(String csvPath) {

        boolean matches = csvPath.endsWith(".csv");
        if(!matches) throw new RuntimeException("请检查文件路径");
    }

    public static void setFrequency(int frequency) {
        TransformCsvData.frequency = frequency;
    }

    @SneakyThrows
    public static void peekCsv(String read,int row,Peek peek){
        log.info("【读取数据】开始 readFile ->{},row->{}", read,row);
        validateCsvPath(read);
        File file = new File(read);
        if (!file.exists()) {
            log.info("【读取数据】 读取文件不存在 readFile->{}", read);
            throw new RuntimeException("读取文件不存在");
        }

        @Cleanup FileInputStream in = new FileInputStream(file);
        @Cleanup InputStreamReader inReader = new InputStreamReader(in, StandardCharsets.UTF_8);
        @Cleanup BufferedReader bufReader = new BufferedReader(inReader);

        String line = null;
        int i = 0;
        while ((line = bufReader.readLine()) != null) {
            if (i<row){
                i++;
                continue;
            }
            line = line+",test";
            String[] split = line.split(",");
            peek.peek(split);
            i++;
        }

        log.info("本次共读出数据集{}条", i);
    }
    public interface Transfer {
        String transfer(String s);
    }

    public interface Peek{
        void peek(String[] csvLine) throws IOException;
    }

}